home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / linux / atari / source / source.lzh / atari-linux-0.01pl3 / fs / ext2 / super.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  14.6 KB  |  536 lines

  1. /*
  2.  *  linux/fs/ext2/super.c
  3.  *
  4.  *  Copyright (C) 1992, 1993  Remy Card (card@masi.ibp.fr)
  5.  *
  6.  *  from
  7.  *
  8.  *  linux/fs/minix/inode.c
  9.  *
  10.  *  Copyright (C) 1991, 1992  Linus Torvalds
  11.  */
  12.  
  13. #include <stdarg.h>
  14.  
  15. #include <asm/segment.h>
  16. #include <asm/system.h>
  17.  
  18. #include <linux/errno.h>
  19. #include <linux/fs.h>
  20. #include <linux/ext2_fs.h>
  21. #include <linux/kernel.h>
  22. #include <linux/sched.h>
  23. #include <linux/stat.h>
  24. #include <linux/string.h>
  25. #include <linux/locks.h>
  26.  
  27. extern int vsprintf (char *, const char *, va_list);
  28.  
  29. void ext2_error (struct super_block * sb, const char * function,
  30.          const char * fmt, ...)
  31. {
  32.     char buf[1024];
  33.     va_list args;
  34.  
  35.     if (!(sb->s_flags & MS_RDONLY)) {
  36.         sb->u.ext2_sb.s_mount_state |= EXT2_ERROR_FS;
  37.         sb->u.ext2_sb.s_es->s_state |= EXT2_ERROR_FS;
  38.         sb->u.ext2_sb.s_sbh->b_dirt = 1;
  39.         sb->s_dirt = 1;
  40.     }
  41.     va_start (args, fmt);
  42.     vsprintf (buf, fmt, args);
  43.     va_end (args);
  44.     printk (
  45. #ifdef KERN_ERR
  46.         KERN_ERR
  47. #endif
  48.         "EXT2-fs error (device %d/%d): %s: %s\n",
  49.         MAJOR(sb->s_dev), MINOR(sb->s_dev), function, buf);
  50. }
  51.  
  52. volatile void ext2_panic (struct super_block * sb, const char * function,
  53.               const char * fmt, ...)
  54. {
  55.     char buf[1024];
  56.     va_list args;
  57.  
  58.     if (!(sb->s_flags & MS_RDONLY)) {
  59.         sb->u.ext2_sb.s_mount_state |= EXT2_ERROR_FS;
  60.         sb->u.ext2_sb.s_es->s_state |= EXT2_ERROR_FS;
  61.         sb->u.ext2_sb.s_sbh->b_dirt = 1;
  62.         sb->s_dirt = 1;
  63.     }
  64.     va_start (args, fmt);
  65.     vsprintf (buf, fmt, args);
  66.     va_end (args);
  67.     panic ("EXT2-fs panic (device %d/%d): %s: %s\n",
  68.            MAJOR(sb->s_dev), MINOR(sb->s_dev), function, buf);
  69. }
  70.  
  71. void ext2_warning (struct super_block * sb, const char * function,
  72.            const char * fmt, ...)
  73. {
  74.     char buf[1024];
  75.     va_list args;
  76.  
  77.     va_start (args, fmt);
  78.     vsprintf (buf, fmt, args);
  79.     va_end (args);
  80.     printk (
  81. #ifdef KERN_WARNING
  82.         KERN_WARNING
  83. #endif
  84.         "EXT2-fs warning (device %d/%d): %s: %s\n",
  85.         MAJOR(sb->s_dev), MINOR(sb->s_dev), function, buf);
  86. }
  87.  
  88. void ext2_put_super (struct super_block * sb)
  89. {
  90.     int i;
  91.  
  92.     lock_super (sb);
  93.     if (!(sb->s_flags & MS_RDONLY)) {
  94.         sb->u.ext2_sb.s_es->s_state = sb->u.ext2_sb.s_mount_state;
  95.         sb->u.ext2_sb.s_sbh->b_dirt = 1;
  96.     }
  97. #ifndef DONT_USE_DCACHE
  98.     ext2_dcache_invalidate (sb->s_dev);
  99. #endif
  100.     sb->s_dev = 0;
  101.     for (i = 0; i < EXT2_MAX_GROUP_DESC; i++)
  102.         if (sb->u.ext2_sb.s_group_desc[i])
  103.             brelse (sb->u.ext2_sb.s_group_desc[i]);
  104.     for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
  105.         if (sb->u.ext2_sb.s_inode_bitmap[i])
  106.             brelse (sb->u.ext2_sb.s_inode_bitmap[i]);
  107.     for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
  108.         if (sb->u.ext2_sb.s_block_bitmap[i])
  109.             brelse (sb->u.ext2_sb.s_block_bitmap[i]);
  110.     brelse (sb->u.ext2_sb.s_sbh);
  111.     unlock_super (sb);
  112.     return;
  113. }
  114.  
  115. static struct super_operations ext2_sops = { 
  116.     ext2_read_inode,
  117.     NULL,
  118.     ext2_write_inode,
  119.     ext2_put_inode,
  120.     ext2_put_super,
  121.     ext2_write_super,
  122.     ext2_statfs,
  123.     ext2_remount
  124. };
  125.  
  126. #ifdef EXT2FS_PRE_02B_COMPAT
  127.  
  128. static int convert_pre_02b_fs (struct super_block * sb,
  129.                    struct buffer_head * bh)
  130. {
  131.     struct ext2_super_block * es;
  132.     struct ext2_old_group_desc old_group_desc [BLOCK_SIZE / sizeof (struct ext2_old_group_desc)];
  133.     struct ext2_group_desc * gdp;
  134.     struct buffer_head * bh2;
  135.     int groups_count;
  136.     int i;
  137.  
  138.     es = (struct ext2_super_block *) bh->b_data;
  139.     bh2 = bread (sb->s_dev, 2, BLOCK_SIZE);
  140.     if (!bh2) {
  141.         printk ("Cannot read descriptor blocks while converting !\n");
  142.         return 0;
  143.     }
  144.     memcpy (old_group_desc, bh2->b_data, BLOCK_SIZE);
  145.     groups_count = (sb->u.ext2_sb.s_blocks_count - 
  146.             sb->u.ext2_sb.s_first_data_block +
  147.             (EXT2_BLOCK_SIZE(sb) * 8) - 1) /
  148.                 (EXT2_BLOCK_SIZE(sb) * 8);
  149.     memset (bh2->b_data, 0, BLOCK_SIZE);
  150.     gdp = (struct ext2_group_desc *) bh2->b_data;
  151.     for (i = 0; i < groups_count; i++) {
  152.         gdp[i].bg_block_bitmap = old_group_desc[i].bg_block_bitmap;
  153.         gdp[i].bg_inode_bitmap = old_group_desc[i].bg_inode_bitmap;
  154.         gdp[i].bg_inode_table = old_group_desc[i].bg_inode_table;
  155.         gdp[i].bg_free_blocks_count = old_group_desc[i].bg_free_blocks_count;
  156.         gdp[i].bg_free_inodes_count = old_group_desc[i].bg_free_inodes_count;
  157.     }
  158.     bh2->b_dirt = 1;
  159.     brelse (bh2);
  160.     es->s_magic = EXT2_SUPER_MAGIC;
  161.     bh->b_dirt = 1;
  162.     sb->s_magic = EXT2_SUPER_MAGIC;
  163.     return 1;
  164. }
  165.  
  166. #endif
  167.  
  168. /*
  169.  * This function has been shamelessly adapted from the msdos fs
  170.  */
  171. static int parse_options (char * options, unsigned long * sb_block,
  172.               unsigned long * mount_options)
  173. {
  174.     char * this_char;
  175.     char * value;
  176.  
  177.     if (!options)
  178.         return 1;
  179.     for (this_char = strtok (options, ",");
  180.          this_char != NULL;
  181.          this_char = strtok (NULL, ",")) {
  182.         if ((value = strchr (this_char, '=')) != NULL)
  183.             *value++ = 0;
  184.         if (!strcmp (this_char, "check"))
  185.             *mount_options |= EXT2_MOUNT_CHECK;
  186.         else if (!strcmp (this_char, "sb")) {
  187.             if (!value || !*value)
  188.                 return 0;
  189.             *sb_block = simple_strtoul (value, &value, 0);
  190.             if (*value)
  191.                 return 0;
  192.         }
  193.         else {
  194.             printk ("EXT2-fs: Unrecognized mount option %s\n", this_char);
  195.             return 0;
  196.         }
  197.     }
  198.     return 1;
  199. }
  200.  
  201. struct super_block * ext2_read_super (struct super_block * s, void * data,
  202.                       int silent)
  203. {
  204.     struct buffer_head * bh;
  205.     struct ext2_super_block * es;
  206.     unsigned long sb_block = 1;
  207.     unsigned long logic_sb_block = 1;
  208.     int dev = s->s_dev;
  209.     int bh_count;
  210.     int i, j;
  211. #ifdef EXT2FS_PRE_02B_COMPAT
  212.     int fs_converted = 0;
  213. #endif
  214.  
  215.     s->u.ext2_sb.s_mount_opt = 0;
  216.     if (!parse_options ((char *) data, &sb_block,
  217.         &s->u.ext2_sb.s_mount_opt)) {
  218.         s->s_dev = 0;
  219.         return NULL;
  220.     }
  221.  
  222.     lock_super (s);
  223.     set_blocksize (dev, BLOCK_SIZE);
  224.     if (!(bh = bread (dev, sb_block, BLOCK_SIZE))) {
  225.         s->s_dev = 0;
  226.         unlock_super (s);
  227.         printk ("EXT2-fs: unable to read superblock\n");
  228.         return NULL;
  229.     }
  230.     es = (struct ext2_super_block *) bh->b_data;
  231.     /* Note: s_es must be initialized s_es as soon as possible because
  232.        some ext2 macro-instructions depend on its value */
  233.     s->u.ext2_sb.s_es = es;
  234.     s->s_magic = es->s_magic;
  235.     if (s->s_magic != EXT2_SUPER_MAGIC
  236. #ifdef EXT2FS_PRE_02B_COMPAT
  237.        && s->s_magic != EXT2_PRE_02B_MAGIC
  238. #endif
  239.        ) {
  240.         s->s_dev = 0;
  241.         unlock_super (s);
  242.         brelse (bh);
  243.         if (!silent)
  244.             printk ("VFS: Can't find an ext2 filesystem on dev 0x%04x.\n",
  245.                 dev);
  246.         return NULL;
  247.     }
  248.     s->s_blocksize = EXT2_MIN_BLOCK_SIZE << es->s_log_block_size;
  249.     s->s_blocksize_bits = EXT2_BLOCK_SIZE_BITS(s);
  250.     if (s->s_blocksize != BLOCK_SIZE && 
  251.         (s->s_blocksize == 1024 || s->s_blocksize == 2048 ||  
  252.          s->s_blocksize == 4096)) {
  253.         unsigned long offset;
  254.  
  255.         brelse (bh);
  256.         set_blocksize (dev, s->s_blocksize);
  257.         logic_sb_block = sb_block / s->s_blocksize;
  258.         offset = sb_block % s->s_blocksize;
  259.         bh = bread (dev, logic_sb_block, s->s_blocksize);
  260.         if(!bh)
  261.             return NULL;
  262.         es = (struct ext2_super_block *) (((char *)bh->b_data) + offset);
  263.         s->u.ext2_sb.s_es = es;
  264.         if (es->s_magic != EXT2_SUPER_MAGIC) {
  265.             s->s_dev = 0;
  266.             unlock_super (s);
  267.             brelse (bh);
  268.             printk ("EXT2-fs: Magic mismatch, very weird !\n");
  269.             return NULL;
  270.         }
  271.     }
  272.     s->u.ext2_sb.s_frag_size = EXT2_MIN_FRAG_SIZE <<
  273.                    es->s_log_frag_size;
  274.     if (s->u.ext2_sb.s_frag_size)
  275.         s->u.ext2_sb.s_frags_per_block = s->s_blocksize /
  276.                            s->u.ext2_sb.s_frag_size;
  277.     else
  278.         s->s_magic = 0;
  279.     s->u.ext2_sb.s_blocks_per_group = es->s_blocks_per_group;
  280.     s->u.ext2_sb.s_frags_per_group = es->s_frags_per_group;
  281.     s->u.ext2_sb.s_inodes_per_group = es->s_inodes_per_group;
  282.     s->u.ext2_sb.s_inodes_per_block = s->s_blocksize /
  283.                       sizeof (struct ext2_inode);
  284.     s->u.ext2_sb.s_desc_per_block = s->s_blocksize /
  285.                     sizeof (struct ext2_group_desc);
  286.     s->u.ext2_sb.s_sbh = bh;
  287.     s->u.ext2_sb.s_es = es;
  288.     s->u.ext2_sb.s_mount_state = es->s_state;
  289.     s->u.ext2_sb.s_rename_lock = 0;
  290.     s->u.ext2_sb.s_rename_wait = NULL;
  291. #ifdef EXT2FS_PRE_02B_COMPAT
  292.     if (s->s_magic == EXT2_PRE_02B_MAGIC) {
  293.         if (es->s_blocks_count > 262144) {
  294.              /* fs > 256 MB can't be converted */ 
  295.             s->s_dev = 0;
  296.             unlock_super (s);
  297.             brelse (bh);
  298.             printk ("EXT2-fs: trying to mount a pre-0.2b file"
  299.                 "system which cannot be converted\n");
  300.             return NULL;
  301.         }
  302.         printk ("EXT2-fs: mounting a pre 0.2b file system, "
  303.             "will try to convert the structure\n");
  304.         if (!(s->s_flags & MS_RDONLY)) {
  305.             s->s_dev = 0;
  306.             unlock_super (s);
  307.             brelse (bh);
  308.             printk ("EXT2-fs: cannot convert a read-only fs\n");
  309.             return NULL;
  310.         }
  311.         if (!convert_pre_02b_fs (s, bh)) {
  312.             s->s_dev = 0;
  313.             unlock_super (s);
  314.             brelse (bh);
  315.             printk ("EXT2-fs: conversion failed !!!\n");
  316.             return NULL;
  317.         }
  318.         printk ("EXT2-fs: conversion succeeded !!!\n");
  319.         fs_converted = 1;
  320.     }
  321. #endif
  322.     if (s->s_magic != EXT2_SUPER_MAGIC) {
  323.         s->s_dev = 0;
  324.         unlock_super (s);
  325.         brelse (bh);
  326.         if (!silent)
  327.             printk ("VFS: Can't find an ext2 filesystem on dev 0x%04x.\n",
  328.                 dev);
  329.         return NULL;
  330.     }
  331.     if (s->s_blocksize != bh->b_size) {
  332.         s->s_dev = 0;
  333.         unlock_super (s);
  334.         brelse (bh);
  335.         if (!silent)
  336.             printk ("VFS: Unsupported blocksize on dev 0x%04x.\n",
  337.                 dev);
  338.         return NULL;
  339.     }
  340.  
  341.     if (s->s_blocksize != s->u.ext2_sb.s_frag_size) {
  342.         s->s_dev = 0;
  343.         unlock_super (s);
  344.         brelse (bh);
  345.         printk ("EXT2-fs: fragsize %lu != blocksize %lu (not supported yet)\n",
  346.             s->u.ext2_sb.s_frag_size, s->s_blocksize);
  347.         return NULL;
  348.     }
  349.  
  350.     s->u.ext2_sb.s_groups_count = (es->s_blocks_count -
  351.                        es->s_first_data_block +
  352.                        EXT2_BLOCKS_PER_GROUP(s) - 1) /
  353.                        EXT2_BLOCKS_PER_GROUP(s);
  354.     for (i = 0; i < EXT2_MAX_GROUP_DESC; i++)
  355.         s->u.ext2_sb.s_group_desc[i] = NULL;
  356.     bh_count = (s->u.ext2_sb.s_groups_count + EXT2_DESC_PER_BLOCK(s) - 1) /
  357.            EXT2_DESC_PER_BLOCK(s);
  358.     if (bh_count > EXT2_MAX_GROUP_DESC) {
  359.         s->s_dev = 0;
  360.         unlock_super (s);
  361.         brelse (bh);
  362.         printk ("EXT2-fs: file system is too big\n");
  363.         return NULL;
  364.     }
  365.     for (i = 0; i < bh_count; i++) {
  366.         s->u.ext2_sb.s_group_desc[i] = bread (dev, logic_sb_block + i + 1,
  367.                               s->s_blocksize);
  368.         if (!s->u.ext2_sb.s_group_desc[i]) {
  369.             s->s_dev = 0;
  370.             unlock_super (s);
  371.             for (j = 0; j < i; j++)
  372.                 brelse (s->u.ext2_sb.s_group_desc[i]);
  373.             brelse (bh);
  374.             printk ("EXT2-fs: unable to read group descriptors\n");
  375.             return NULL;
  376.         }
  377.     }
  378.     for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) {
  379.         s->u.ext2_sb.s_inode_bitmap_number[i] = 0;
  380.         s->u.ext2_sb.s_inode_bitmap[i] = NULL;
  381.         s->u.ext2_sb.s_block_bitmap_number[i] = 0;
  382.         s->u.ext2_sb.s_block_bitmap[i] = NULL;
  383.     }
  384.     s->u.ext2_sb.s_loaded_inode_bitmaps = 0;
  385.     s->u.ext2_sb.s_loaded_block_bitmaps = 0;
  386.     unlock_super (s);
  387.     /* set up enough so that it can read an inode */
  388.     s->s_dev = dev;
  389.     s->s_op = &ext2_sops;
  390.     if (!(s->s_mounted = iget (s, EXT2_ROOT_INO))) {
  391.         s->s_dev = 0;
  392.         for (i = 0; i < EXT2_MAX_GROUP_DESC; i++)
  393.             if (s->u.ext2_sb.s_group_desc[i])
  394.                 brelse (s->u.ext2_sb.s_group_desc[i]);
  395.         brelse (bh);
  396.         printk ("EXT2-fs: get root inode failed\n");
  397.         return NULL;
  398.     }
  399.     if (!(s->s_flags & MS_RDONLY)) {
  400.         es->s_state &= ~EXT2_VALID_FS;
  401.         if (!es->s_max_mnt_count)
  402.             es->s_max_mnt_count = EXT2_DFL_MAX_MNT_COUNT;
  403.         es->s_mnt_count++;
  404.         es->s_mtime = CURRENT_TIME;
  405.         bh->b_dirt = 1;
  406.         s->s_dirt = 1;
  407.     }
  408. #ifdef EXT2FS_PRE_02B_COMPAT
  409.     if (fs_converted) {
  410.         for (i = 0; i < bh_count; i++)
  411.             s->u.ext2_sb.s_group_desc[i]->b_dirt = 1;
  412.         s->s_dirt = 1;
  413.     }
  414. #endif
  415.     if (!(s->u.ext2_sb.s_mount_state & EXT2_VALID_FS))
  416.         printk ("EXT2-fs warning: mounting unchecked file system, "
  417.             "running e2fsck is recommended\n");
  418.      else if (s->u.ext2_sb.s_mount_state & EXT2_ERROR_FS)
  419.         printk ("EXT2-fs warning: mounting file system with errors, "
  420.             "running e2fsck is recommended\n");
  421.     else if (es->s_mnt_count >= es->s_max_mnt_count)
  422.         printk ("EXT2-fs warning: maximal mount count reached, "
  423.                         "running e2fsck is recommended\n");
  424.     if (s->u.ext2_sb.s_mount_opt & EXT2_MOUNT_CHECK) {
  425.         printk ("[EXT II FS %s, %s, bs=%lu, fs=%lu, gc=%lu, bpg=%lu, ipg=%lu]\n",
  426.             EXT2FS_VERSION, EXT2FS_DATE, s->s_blocksize,
  427.             s->u.ext2_sb.s_frag_size, s->u.ext2_sb.s_groups_count,
  428.             EXT2_BLOCKS_PER_GROUP(s), EXT2_INODES_PER_GROUP(s));
  429.         ext2_check_blocks_bitmap (s);
  430.         ext2_check_inodes_bitmap (s);
  431.     }
  432.     return s;
  433. }
  434.  
  435. static void ext2_commit_super (struct super_block * sb,
  436.                    struct ext2_super_block * es)
  437. {
  438.     es->s_wtime = CURRENT_TIME;
  439.     sb->u.ext2_sb.s_sbh->b_dirt = 1;
  440.     sb->s_dirt = 0;
  441. }
  442.  
  443. /*
  444.  * In the second extended file system, it is not necessary to
  445.  * write the super block since we use a mapping of the
  446.  * disk super block in a buffer.
  447.  *
  448.  * However, this function is still used to set the fs valid
  449.  * flags to 0.  We need to set this flag to 0 since the fs
  450.  * may have been checked while mounted and e2fsck may have
  451.  * set s_state to EXT2_VALID_FS after some corrections.
  452.  */
  453.  
  454. void ext2_write_super (struct super_block * sb)
  455. {
  456.     struct ext2_super_block * es;
  457.  
  458.     if (!(sb->s_flags & MS_RDONLY)) {
  459.         es = sb->u.ext2_sb.s_es;
  460.  
  461.         ext2_debug ("setting valid to 0\n");
  462.  
  463.         if (es->s_state & EXT2_VALID_FS) {
  464.             es->s_state &= ~EXT2_VALID_FS;
  465.             es->s_mtime = CURRENT_TIME;
  466.         }
  467.         ext2_commit_super (sb, es);
  468.     }
  469.     sb->s_dirt = 0;
  470. }
  471.  
  472. int ext2_remount (struct super_block * sb, int * flags)
  473. {
  474.     struct ext2_super_block * es;
  475.  
  476.     es = sb->u.ext2_sb.s_es;
  477.     if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
  478.         return 0;
  479.     if (*flags & MS_RDONLY) {
  480.         if (es->s_state & EXT2_VALID_FS ||
  481.             !(sb->u.ext2_sb.s_mount_state & EXT2_VALID_FS))
  482.             return 0;
  483.         /* OK, we are remounting a valid rw partition rdonly, so set
  484.            the rdonly flag and then mark the partition as valid
  485.            again. */
  486.         es->s_state = sb->u.ext2_sb.s_mount_state;
  487.         es->s_mtime = CURRENT_TIME;
  488.         sb->u.ext2_sb.s_sbh->b_dirt = 1;
  489.         sb->s_dirt = 1;
  490.         ext2_commit_super (sb, es);
  491.     }
  492.     else {
  493.         /* Mounting a RDONLY partition read-write, so reread and
  494.            store the current valid flag.  (It may have been changed 
  495.            by e2fsck since we originally mounted the partition.)  */
  496.         sb->u.ext2_sb.s_mount_state = es->s_state;
  497.         es->s_state &= ~EXT2_VALID_FS;
  498.         if (!es->s_max_mnt_count)
  499.             es->s_max_mnt_count = EXT2_DFL_MAX_MNT_COUNT;
  500.         es->s_mnt_count++;
  501.         es->s_mtime = CURRENT_TIME;
  502.         sb->u.ext2_sb.s_sbh->b_dirt = 1;
  503.         sb->s_dirt = 1;
  504.         if (!(sb->u.ext2_sb.s_mount_state & EXT2_VALID_FS))
  505.             printk ("EXT2-fs warning: remounting unchecked fs, "
  506.                 "running e2fsck is recommended\n");
  507.         else if ((sb->u.ext2_sb.s_mount_state & EXT2_ERROR_FS))
  508.             printk ("EXT2-fs warning: remounting fs with errors, "
  509.                 "running e2fsck is recommended\n");
  510.         else if (es->s_mnt_count >= es->s_max_mnt_count)
  511.             printk ("EXT2-fs warning: maximal mount count reached, "
  512.                             "running e2fsck is recommended\n");
  513.     }
  514.     return 0;
  515. }
  516.  
  517. void ext2_statfs (struct super_block * sb, struct statfs * buf)
  518. {
  519.     long tmp;
  520.  
  521.     put_fs_long (EXT2_SUPER_MAGIC, &buf->f_type);
  522.     put_fs_long (sb->s_blocksize, &buf->f_bsize);
  523.     put_fs_long (sb->u.ext2_sb.s_es->s_blocks_count, &buf->f_blocks);
  524.     tmp = ext2_count_free_blocks (sb);
  525.     put_fs_long (tmp, &buf->f_bfree);
  526.     if (tmp >= sb->u.ext2_sb.s_es->s_r_blocks_count)
  527.         put_fs_long (tmp - sb->u.ext2_sb.s_es->s_r_blocks_count,
  528.                  &buf->f_bavail);
  529.     else
  530.         put_fs_long (0, &buf->f_bavail);
  531.     put_fs_long (sb->u.ext2_sb.s_es->s_inodes_count, &buf->f_files);
  532.     put_fs_long (ext2_count_free_inodes (sb), &buf->f_ffree);
  533.     put_fs_long (EXT2_NAME_LEN, &buf->f_namelen);
  534.     /* Don't know what value to put in buf->f_fsid */
  535. }
  536.